home *** CD-ROM | disk | FTP | other *** search
-
- /* HY-PHEN-A-TION */
- /* */
- /* Raffi J. Kasparian */
- /* */
- /* Please set the following three defines to appropriate */
- /* values if their default settings are not appropriate. */
-
- #define AllowMixedCaseDoubleConsonants true
- /* if, for example, "Ss" or "sS" might occur in the */
- /* middle of the word (as in "paSsion"). */
-
- #define AllowZeroLengthWords false
- /* if the length byte might be a zero. */
-
- #define AllowMultipleConsonants true
- /* if multiple ( >2 ) same-consonants are po"sssss"ible. */
-
- #define uchar unsigned char
- #define ulong unsigned long
- #define kHyphen 0x2D
- #define v( a ) ( a == 'A' || a == 'a' || \
- a == 'E' || a == 'e' || \
- a == 'I' || a == 'i' || \
- a == 'O' || a == 'o' || \
- a == 'U' || a == 'u' )
-
- static Boolean vowelTable[128] = {
- v(0), v(1), v(2), v(3), v(4), v(5), v(6), v(7), v(8),
- v(9), v(10), v(11), v(12), v(13), v(14), v(15), v(16),
- v(17), v(18), v(19), v(20), v(21), v(22), v(23), v(24),
- v(25), v(26), v(27), v(28), v(29), v(30), v(31), v(32),
- v(33), v(34), v(35), v(36), v(37), v(38), v(39), v(40),
- v(41), v(42), v(43), v(44), v(45), v(46), v(47), v(48),
- v(49), v(50), v(51), v(52), v(53), v(54), v(55), v(56),
- v(57), v(58), v(59), v(60), v(61), v(62), v(63), v(64),
- v(65), v(66), v(67), v(68), v(69), v(70), v(71), v(72),
- v(73), v(74), v(75), v(76), v(77), v(78), v(79), v(80),
- v(81), v(82), v(83), v(84), v(85), v(86), v(87), v(88),
- v(89), v(90), v(91), v(92), v(93), v(94), v(95), v(96),
- v(97), v(98), v(99), v(100), v(101), v(102), v(103),
- v(104), v(105), v(106), v(107), v(108), v(109), v(110),
- v(111), v(112), v(113), v(114), v(115), v(116), v(117),
- v(118), v(119), v(120), v(121), v(122), v(123), v(124),
- v(125), v(126), v(127)
- };
-
- void *InitHyphenation( ulong maxRAM )
- {
- return (void*)vowelTable;
- }
-
- void Hyphenate( privateDataPtr, inPtr, outPtr )
- void *privateDataPtr;
- Str255 *inPtr;
- Str255 *outPtr;
- {
- #define mIsVowel( a ) ( ((Boolean*)privateDataPtr)[a] )
- #define mIsConsonant( a ) ( ! mIsVowel( a ) )
-
- #if AllowMixedCaseDoubleConsonants
- #define mIsDoubleConsonant( in )\
- ( *in == ( a = *( in + 1 ) ) || *in == a + 'a' - 'A' \
- || *in == a + 'A' - 'a' )
- #else
- #define mIsDoubleConsonant( in ) ( *in == *( in + 1 ) )
- #endif
-
- register uchar *in, *out, *out0, *inLast, *lastVowel;
- #if AllowMixedCaseDoubleConsonants
- register uchar a;
- #endif
-
- in = *inPtr;
- out = out0 = *outPtr;
- lastVowel = inLast = in + *in;
-
- /* working from back to front of the word, locate the */
- /* last vowel not including final 'e', 'es', or 'ed. */
- if( mIsVowel( *lastVowel ) ){
- if( *lastVowel == 'e' || *lastVowel == 'E' ){
- lastVowel--;
- goto FIND_LAST_VOWEL;
- }
- else goto ALGORITHM;
- }
- switch( *lastVowel-- ){
- case 's': case 'd': case 'S': case 'D':
- if( *lastVowel == 'e' || *lastVowel == 'E' )
- lastVowel--;
- break;
- #if AllowZeroLengthWords
- case '\0': goto COPY_TO_END;
- #endif
- }
- FIND_LAST_VOWEL: do{
- if( lastVowel == in ) goto COPY_TO_END;
- if( mIsVowel( *lastVowel ) ) break;
- lastVowel--;
- }while( true );
-
- ALGORITHM:
- /* Working forwards from the beginning of the word */
- /* until lastVowel is reached, hyphenate every */
- /* vowel/consonant pair unless the vowel is followed by */
- /* a double consonant. In this case, hyphenate between */
- /* the double consonant. This method meets the */
- /* hyphenation requirements without having to deal */
- /* directly with all the letter combination rules. */
-
- *out++ = *in++; /* copy length byte */
- while( true ){
- while( mIsConsonant( *in ) )
- *out++ = *in++;
- do{
- if( in == lastVowel ) goto COPY_TO_END;
- *out++ = *in++;
- }while( mIsVowel( *in ) );
-
- /* handle double or multiple consonants */
- #if AllowMultipleConsonants
- while( mIsDoubleConsonant( in ) ) *out++ = *in++;
- #else
- if( mIsDoubleConsonant( in ) ) *out++ = *in++;
- #endif
- *out++ = kHyphen; *out++ = *in++; (*out0)++;
- }
- COPY_TO_END: do *out++ = *in++; while( in <= inLast );
-
- #undef mIsVowel
- #undef mIsConsonant
- #undef mIsDoubleConsonant
- }
-